package moodish.dummy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import moodish.comm.ClientComm;
import moodish.comm.ClientSideMessage;
import moodish.comm.ServerSideMessage.Type;

/**
 * Communication class for Moodish clients. Moodish clients must 
 * communicate with a MoodishServer exclusively through this class. 
 * 
 * @author group27
 * @version 1
 */

public class ClientCommDummy implements ClientComm {

	private String nickname;
	private Socket socket = null;
	private DealWithServerMessages dealserver;
	private BlockingQueue<ClienteSideMessage > messages = new LinkedBlockingQueue<ClienteSideMessage >();
	
	/**
	 * Establish a connection to a Moodish server. 
	 * 
	 * @param host                    Address of the server. For instance "localhost", "192.168.1.1", and so on.
	 * @param nickname                The nickname to use for the client.
	 * @throws UnknownHostException   Thrown if the host cannot be found.
	 * @throws IOException            Thrown if a connection cannot be established.
	 */
	
	@Override
	public void connect(String serverAddress, String nickname) {
		try {
			this.nickname=nickname;
			InetAddress Address = InetAddress.getByName(serverAddress);
			socket = new Socket(Address, ServerCommDummy.PORT);
			dealserver = new DealWithServerMessages(socket,this, nickname);
			dealserver.start();
			sendConnectedMessage();
			
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			
		}

	}
	
	/**
	 * Check if currently connected to a host.
	 * 
	 * @return <b>true</b> if currently connected to a host, <b>false</b> otherwise.
	 */
	
	@Override
	public boolean isConnected() {
		return !(socket.isClosed());
	}
	
	/**
	 * Disconnect from a Moodish server. 
	 */	
	
	
	@Override
	public void disconnect() {
		sendDisconnectedMessage();
		try {
			socket.close();
		} catch (IOException e) {
			
		}

	}
	
	/** 
	 * Check if a message from the server is pending.
	 * 
	 * @return <b>true</b> if a message from the server is currently pending, otherwise <b>false</b>.
	 */
	
	@Override
	public synchronized boolean hasNextMessage() {
		return !messages.isEmpty();
	}
	
	/**
	 * Get the next message received from the server. If no message 
	 * is has been received, the method blocks until a message has 
	 * been received. If no message will ever be received (connection is down), null is returned.
	 * 
	 * @return The next message sent by the server to the client or null if no message will ever be received (disconnected from server).
	 */
	
	@Override
	public ClienteSideMessage getNextMessage() {
		ClienteSideMessage  message = messages.element();
		messages.remove();
		return message;
	}
	
	/**
	 * Send a Moodish message from this client to the server which should then relay the message to all freinds.
	 * 
	 * @param moodishMessage The Moodish message to be sent.
	 */
	
	@Override
	public void sendMoodishMessage(String moodishMessage) {
		dealserver.sendMoodishMessage(moodishMessage);
	}
	
	/**
	 * Request to be friend of another client.
	 * 
	 * @param nickname the nickname of the client that should be friend.
	 */

	@Override
	public void friendship(String nickname) {
		dealserver.friendship(nickname);
	}
	
	/**
	 * Request to unfriend of  a client.
	 * 
	 * @param nickname the nickname of the client currently friend that should be unfriended. 
	 */

	@Override
	public void unfriendship(String nickname) {
		dealserver.unfriendship(nickname);
	}

	/**
	 * Adds a message to a list.
	 * 
	 * @param message message to add.
	 * 
	 */
	
	public synchronized void addMessage(ClienteSideMessage message) {
		messages.add(message);
		
	}
	
	/**
	 * Sends a Connected message from this cliente to the server.
	 * 
	 *
	 */
	
	public void sendConnectedMessage() {
		dealserver.sendConnectedMessage();
	}
	
	/**
	 * Sends a Disconnected message from this cliente to the server.
	 * 
	 *
	 */
	
	public void sendDisconnectedMessage() {
		dealserver.sendDisconnectedMessage();
	}
	

}
